﻿using MultiLang;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32;

namespace Rsdn.Janus.Framework
{
    public static class SharedFunctions
    {
        private const int WaitTimeout = 20 * 1000; //20 seconds

        public static bool StartJanus()
        {
            bool ret = false;
            const string JANUS_EXE = "Janus.exe";                     //MLHIDE
            Stopwatch stopwatch = new Stopwatch();
            string registeredApplication = GetRegisteredApplication();
            if (string.IsNullOrEmpty(registeredApplication))
            {
                registeredApplication = JANUS_EXE;
            }

            if (File.Exists(registeredApplication))
            {
                Process janus = new Process();
                janus.StartInfo.FileName = Path.GetFullPath(registeredApplication);
                //MessageBox.
                Console.WriteLine(janus.StartInfo.FileName);
                stopwatch = new Stopwatch();
                stopwatch.Start();
                janus.Start();
                janus.WaitForInputIdle(WaitTimeout);

                Console.WriteLine(string.Format("***Finish wait {0}", stopwatch.ElapsedMilliseconds)); //MLHIDE

                // give a chance to start application
                Thread.Sleep(1000);
                IntPtr hEvent = SharedEvents.OpenEvent(SharedConstants.JanusStartedEvent);
                int le = Marshal.GetLastWin32Error();
                if (IntPtr.Zero == hEvent)
                {
                    Console.WriteLine("OpenEvent failed");            //MLHIDE
                    return false; // Exit 
                }

                AutoResetEvent autoResetEvent = SharedEvents.CreateSlaveEvent(hEvent);

                // Wait 10 seconds for InvalidProgramException start
                if (autoResetEvent.WaitOne(WaitTimeout))
                {
                    Console.WriteLine(string.Format("***Init finished {0}", stopwatch.ElapsedMilliseconds)); //MLHIDE
                    Thread.Sleep(1000);
                    ret = true;
                }
            }

            Console.WriteLine(string.Format("***End start {0}", stopwatch.ElapsedMilliseconds)); //MLHIDE

            return ret;
        }

        private const string _keyPath = @"Software\Rsdn\Janus";   //MLHIDE
        private const string _keyName = "AppPath";                           //MLHIDE

        /// <summary>
        /// Store the full application path in registry.
        /// </summary>
        /// <param name="appPath">The application path.</param>
        public static void RegisterApplication(string appPath)
        {
            //string appPath = Path.GetDirectoryName(Application.ExecutablePath);

            using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(_keyPath))
            {
                if (registryKey == null)
                {
                    throw new ApplicationException(String.Format(ml.ml_string(10, "Невозможно создать ветку реестра {0}"), _keyPath));
                }

                registryKey.SetValue(_keyName, appPath);
            }
        }

        public static string GetRegisteredApplication()
        {
            string ret = "";
            using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(_keyPath))
            {
                if (registryKey == null)
                {
                    throw new ApplicationException(String.Format(ml.ml_string(11, "Невозможно открыть ветку реестра {0}"), _keyPath));
                }

                object path = registryKey.GetValue(_keyName);
                if (path == null)
                {
                    throw new ApplicationException(
                        String.Format(
                            ml.ml_string(12, "Невозможно прочитать содержимое переменной {0} в ветке реестра {1}"), _keyName, _keyPath));
                }

                ret = path.ToString();
            }

            return ret;
        }
    }
}
